import java.util.LinkedList;


public class DFSSearcher implements Agente {

	private  Map<DFSState> map;
	private boolean firstRun=true;
	private LinkedList<Direccion> camino = new LinkedList<Direccion>();
	
	
	@Override
	public void Inicializar(Observacion obs, char[][] charmap) {
		
		this.map=new Map<DFSState>(charmap);
		
		
		for (int i=0; i<charmap.length; i++)  // construimos el mapa de estados
			for (int j=0; j<charmap[0].length;j++) {
				DFSState s=new DFSState(i,j,map);
				map.setState(i, j, s);
			}
		

	}

	@Override
	public Direccion Mover(Observacion obs, long tiempo_restante) {
					// no haremos nada con respecto a tiempo_restante... cruzando dedos
		int expanded=0;

		
		if (firstRun) {

			LinkedList<DFSState> open;
			
			firstRun=false;
			
			DFSState goal=null;
			open=new LinkedList<DFSState>();		
			open.add(map.getState(obs.getPosX(),obs.getPosY()));
			
			while (!open.isEmpty()) {
				
				DFSState s=open.removeFirst();
				
				if (s.isClosed()) continue;
				s.close();
				
				if (s.isGoal(obs)) {
					goal=s;
					break;
				}
				
				LinkedList<DFSState> succ; 
				succ=s.successors();              // Expande sucesores
				
				expanded++;
								
				while (!succ.isEmpty()) {
					DFSState sucesor=succ.removeLast();
					if (!sucesor.isClosed()) {
						open.add(sucesor);
						sucesor.setFather(s);
					}
				}
				
			}
			
			if (goal==null) {
				System.out.println("No se pudo encontrar el objetivo!?");
				System.exit(1);
			}
			
			while (goal.getFather()!=null) {
				Direccion d=Direccion.getDireccion(goal.getX()-goal.getFather().getX(),goal.getY()-goal.getFather().getY());
				camino.addFirst(d);
				goal=goal.getFather();
				
			}
			System.out.println("Expandí "+expanded+" estados");
						
		}
		
		
		Direccion next=camino.remove();		
		return next;


	}

}
